package com.jctrip.hotel.management.service;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jctrip.hotel.common.util.BeanUtil;
import com.jctrip.hotel.common.util.RedisUtil;
import com.jctrip.hotel.domain.dao.*;
import com.jctrip.hotel.domain.entity.*;
import com.jctrip.hotel.management.client.FeizhuClient;
import com.jctrip.hotel.management.client.XieChengClient;
import com.jctrip.hotel.management.model.param.*;
import com.jctrip.hotel.management.model.result.GetAllPricePolicyResult;
import com.jctrip.hotel.management.model.result.GetFeizhuPricePolicyResult;
import com.jctrip.hotel.management.model.result.GetXieChengPricePolicyResult;
import com.jctrip.hotel.management.model.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PricePolicyService {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private HtPricePolicyDao htPricePolicyDao;

    @Autowired
    private HtPricePolicyRangeDao htPricePolicyRangeDao;

    @Autowired
    private HtRouteInfoDao htRouteInfoDao;

    @Autowired
    private HtSourceCodeDao htSourceCodeDao;

    @Autowired
    private HtSourceInfoDao htSourceInfoDao;

    @Autowired
    private FeizhuClient feizhuClient;

    @Autowired
    private XieChengClient xieChengClient;

    public GetAllPricePolicyResult listAllPricePolicy(GetAllPricePolicyParam param) {
        HtRouteInfo htRouteInfo = htRouteInfoDao.selectList(null).stream()
                .filter(e -> e.getRouteName().equals(param.getRouteName())).findAny().orElse(null);
        if (Objects.isNull(htRouteInfo)) {
            throw new RuntimeException("渠道信息有误");
        }
        List<HtPricePolicy> htPricePolicies = htPricePolicyDao.selectList(new LambdaQueryWrapper<HtPricePolicy>()
                .eq(HtPricePolicy::getRouteId, htRouteInfo.getRouteId())
                .orderByAsc(HtPricePolicy::getRouteId));
        List<GetAllPricePolicyResult.PricePolicyInfo> pricePolicyInfoList = new ArrayList<>();
        for (HtPricePolicy htPricePolicy : htPricePolicies) {
            GetAllPricePolicyResult.PricePolicyInfo pricePolicyInfo = GetAllPricePolicyResult.PricePolicyInfo.builder().build();
            if (Objects.isNull(pricePolicyInfo)) {
                continue;
            }
            BeanUtil.copyProperties(htPricePolicy, pricePolicyInfo);
            pricePolicyInfo.setId(String.valueOf(htPricePolicy.getId()));
            pricePolicyInfo.setRouteName(htRouteInfoDao.selectOne(new LambdaQueryWrapper<HtRouteInfo>()
                    .eq(HtRouteInfo::getRouteId, htPricePolicy.getRouteId())).getRouteName());
            pricePolicyInfo.setSourceName(StringUtils.isNotBlank(pricePolicyInfo.getSourceCode()) ?
                    htSourceCodeDao.selectOne(new LambdaQueryWrapper<HtSourceCode>()
                            .eq(HtSourceCode::getCode, pricePolicyInfo.getSourceCode())).getName() : null);
            pricePolicyInfo.setKeyInfos(getKeyInfos(htPricePolicy));
            // 获取政策对应的加价区间
            List<HtPricePolicyRange> htPricePolicyRanges = htPricePolicyRangeDao.selectList(new LambdaQueryWrapper<HtPricePolicyRange>()
                    .eq(HtPricePolicyRange::getPricePolicyId, htPricePolicy.getPricePolicyId())
                    .orderByAsc(HtPricePolicyRange::getRangePriceMin));
            if (CollectionUtil.isEmpty(htPricePolicyRanges)) {
                continue;
            }
            List<GetAllPricePolicyResult.PricePolicyRangeInfo> pricePolicyRangeInfoList = new ArrayList<>();
            for (HtPricePolicyRange htPricePolicyRange : htPricePolicyRanges) {
                GetAllPricePolicyResult.PricePolicyRangeInfo pricePolicyRangeInfo = GetAllPricePolicyResult.PricePolicyRangeInfo.builder().build();
                BeanUtil.copyProperties(htPricePolicyRange, pricePolicyRangeInfo);
                pricePolicyRangeInfoList.add(pricePolicyRangeInfo);
            }
            pricePolicyInfo.setPricePolicyRangeInfoList(pricePolicyRangeInfoList);
            pricePolicyInfoList.add(pricePolicyInfo);
        }
        return GetAllPricePolicyResult.builder()
                .pricePolicyInfoList(pricePolicyInfoList)
                .build();
    }

    public Boolean editPricePolicy(@RequestBody UpdatePricePolicyParam param) {
        if (CollectionUtil.isEmpty(param.getKeyInfos())) {
            throw new RuntimeException("参数异常");
        }
        HtPricePolicy htPricePolicy = new HtPricePolicy();
        BeanUtil.copyProperties(param, htPricePolicy);
        htPricePolicy.setId(Long.valueOf(param.getId()));
        // routeId 和 对应的价格政策配置id肯定是唯一值 作为redis的Key
        String key = htPricePolicy.getRouteId() + "_" + htPricePolicy.getPricePolicyId();
        redisUtil.del(key);
        htPricePolicy.setSourceIds(solveKeyInfo(param.getKeyInfos()));
        htPricePolicyDao.updateById(htPricePolicy);
        // 删除原来的溢价区间
        htPricePolicyRangeDao.delete(new LambdaQueryWrapper<HtPricePolicyRange>()
                .eq(HtPricePolicyRange::getPricePolicyId, param.getPricePolicyId()));
        // 将新的溢价区间存到区间表中
        param.getPricePolicyRangeInfoList().forEach(pricePolicyRangeInfo -> {
            HtPricePolicyRange htPricePolicyRange = new HtPricePolicyRange();
            BeanUtil.copyProperties(pricePolicyRangeInfo, htPricePolicyRange);
            htPricePolicyRange.setPricePolicyId(param.getPricePolicyId());
            htPricePolicyRangeDao.insert(htPricePolicyRange);
        });
        redisUtil.del(key);
        return true;
    }

    public Result<GetFeizhuPricePolicyResult> getFeizhuPricePolicy(String routeId, Long pageNum, Long pageSize) {
        if (StringUtils.isBlank(routeId)) {
            throw new RuntimeException("参数异常");
        }
        return feizhuClient.getPricePolicy(routeId,
                pageNum != null && pageNum > 0L ? pageNum : 1L,
                pageSize != null && pageSize > 0L ? pageSize : 10L);
    }

    public Result<GetXieChengPricePolicyResult> getXieChengPricePolicy(String routeId, Long pageNum, Long pageSize) {
        if (StringUtils.isBlank(routeId)) {
            throw new RuntimeException("参数异常");
        }
        return xieChengClient.queryPricePolicys(routeId,
                pageNum != null && pageNum > 0L ? pageNum : 1L,
                pageSize != null && pageSize > 0L ? pageSize : 10L);
    }

    public Result<String> insertFliggyPricePolicy(InsertFeizhuPricePolicyParam param) {
        return feizhuClient.insertFliggyPricePolicy(param);
    }

    public Result<String> updateFliggyPricePolicy(UpdateFeizhuPricePolicyParam param) {
        return feizhuClient.updateFliggyPricePolicy(param);
    }

    public Result<String> updateFliggyPricePolicyRange(UpdateFeizhuPricePolicyRangeParam param) {
        return feizhuClient.updateFliggyPricePolicyRange(param);
    }

    public Result<String> updateXiechengPricePolicy(UpdateXiechengPricePolicyParam updateXiechengPricePolicyParam) {
        return xieChengClient.updatePricePolicy(updateXiechengPricePolicyParam);
    }

    public Result<String> updateXiechengPricePolicyRange(UpdateXiechengPricePolicyRangeParam updateXiechengPricePolicyRangeParam) {
        return xieChengClient.updatePricePolicyRange(updateXiechengPricePolicyRangeParam);
    }

    private List<GetAllPricePolicyResult.KeyInfo> getKeyInfos(HtPricePolicy htPricePolicy) {
        List<GetAllPricePolicyResult.KeyInfo> keyInfos = new ArrayList<>();
        String[] keyArray = htPricePolicy.getSourceIds().split(",");
        Map<String, Integer> map = new HashMap<>();
        for (String sourceId : keyArray) {
            if (!map.containsKey(sourceId)) {
                map.put(sourceId, 1);
            } else {
                map.put(sourceId, map.get(sourceId) + 1);
            }
        }

        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            GetAllPricePolicyResult.KeyInfo keyInfo = GetAllPricePolicyResult.KeyInfo.builder()
                    .sourceId(entry.getKey()).times(entry.getValue()).build();
            keyInfo.setSourceName(Optional.ofNullable(htSourceInfoDao.selectOne(new LambdaQueryWrapper<HtSourceInfo>()
                    .eq(HtSourceInfo::getSourceId, entry.getKey()))).orElse(new HtSourceInfo()).getSourceName());
            keyInfos.add(keyInfo);
        }
        return keyInfos;
    }

    private String solveKeyInfo(List<GetAllPricePolicyResult.KeyInfo> keyInfos) {
        StringBuffer stringBuffer = new StringBuffer();
        keyInfos.forEach(keyInfo -> {
            for (int i = 0; i < keyInfo.getTimes(); i++) {
                stringBuffer.append(",");
                stringBuffer.append(keyInfo.getSourceId());
            }
        });
        return stringBuffer.substring(1);
    }
}
